package 设计模式.结构型模式.装饰模式__奶茶加小料;

/**
 * @Author kirito
 * @Date 2024/1/22 11:08
 * @PackageName:设计模式.装饰模式
 * @ClassName: Test01
 * @Description:
 * @Version 1.0
 *
 * 我们来说说装饰模式的出发点，从图中可以看到，接口 Component 其实已经有了 ConcreteComponentA 和 ConcreteComponentB 两个实现类了，
 * 但是，如果我们要增强这两个实现类的话，我们就可以采用装饰模式，用具体的装饰器来装饰实现类，以达到增强的目的。
 * 从名字来简单解释下装饰器。既然说是装饰，那么往往就是添加小功能这种，而且，我们要满足可以添加多个小功能。最简单的，代理模式就可以实现功能的增强，
 * 但是代理不容易实现多个功能的增强，当然你可以说用代理包装代理的多层包装方式，但是那样的话代码就复杂了。
 * 首先明白一些简单的概念，从图中我们看到，所有的具体装饰者们 ConcreteDecorator*** 都可以作为 Component 来使用，
 * 因为它们都实现了 Component 中的所有接口。它们和 Component 实现类 ConcreteComponent* 的区别是，
 * 它们只是装饰者，起装饰作用，也就是即使它们看上去牛逼轰轰，但是它们都只是在具体的实现中加了层皮来装饰**而已。
 * 注意这段话中混杂在各个名词中的 Component 和 Decorator，别搞混了。
 *
 * 最近大街上流行起来了“快乐柠檬”，我们把快乐柠檬的饮料分为三类：红茶、绿茶、咖啡，在这三大类的基础上，
 * 又增加了许多的口味，什么金桔柠檬红茶、金桔柠檬珍珠绿茶、芒果红茶、芒果绿茶、芒果珍珠红茶、烤珍珠红茶、烤珍珠芒果绿茶、
 * 椰香胚芽咖啡、焦糖可可咖啡等等，每家店都有很长的菜单，但是仔细看下，其实原料也没几样，但是可以搭配出很多组合，
 * 如果顾客需要，很多没出现在菜单中的饮料他们也是可以做的。
 *
 * 在这个例子中，红茶、绿茶、咖啡是最基础的饮料，其他的像金桔柠檬、芒果、珍珠、椰果、焦糖等都属于装饰用的。
 * 当然，在开发中，我们确实可以像门店一样，开发这些类：LemonBlackTea、LemonGreenTea、MangoBlackTea、
 * MangoLemonGreenTea......但是，很快我们就发现，这样子干肯定是不行的，这会导致我们需要组合出所有的可能，
 * 而且如果客人需要在红茶中加双份柠檬怎么办？三份柠檬怎么办？
 *
 *
 */
public class Test01 {
    //看客户端调用：
    public static void main(String[] args) {
        // 首先，我们需要一个基础饮料，红茶、绿茶或咖啡
        Beverage beverage = new GreenTea();
        // 开始装饰
        beverage = new Lemon(beverage); // 先加一份柠檬
        beverage = new Mongo(beverage); // 再加一份芒果

        System.out.println(beverage.getDescription() + " 价格：￥" + beverage.cost());
        //"绿茶, 加柠檬, 加芒果 价格：￥16"
//        如果我们需要芒果-珍珠-双份柠檬-红茶： o.0
        Beverage ttt = new Mongo(new Lemon(new Lemon(new BlackTea())));
        System.out.println(ttt.getDescription() + " 价格：￥" + ttt.cost());
    }
}
